﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web.Script.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace BeerManagementSystem
{
    class WebConnector
    {
        private User SendRequestGetUser(User user)

        {
            var webUser = new WebUserGetInfo[1];
            if (user.Last_WebUpdate != null)
            {
                webUser[0] = new WebUserGetInfo
                    {
                        Id = user.ID,
                        Timestamp = (long)user.Last_WebUpdate
                    };
            }
            else
            {
                return user;
            }
            string json = "WebUser=" + JsonConvert.SerializeObject(webUser)
                          + "&shaFromBMS=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
//            string postData = "WebUser=[{\"id\":\"" + user.ID + "\", \"timestamp\":\"" + ToUnixTimespan((DateTime)user.Last_WebUpdate) +"\"}]"
//                              + "&shaFromBMS=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
#if DEBUG
            Console.WriteLine(@"SendRequest:" + @"GetWebUser: " + json + "\n"+ user.Last_WebUpdate.ToString());
#endif
            // Create a request using a URL that can receive a post. 
            var request = (HttpWebRequest)WebRequest.Create("http://www.schmidtwoch.com/sites/default/bms-actions/getUserInfos.php");
            // Set the Method property of the request to POST.
            request.Method = "POST";
            // Create POST data and convert it to a byte array.
            //string postData = "testname=TEST";
            byte[] byteArray = Encoding.UTF8.GetBytes(json);
            // Set the ContentType property of the WebRequest.
            request.ContentType = "application/x-www-form-urlencoded";
            // Set the ContentLength property of the WebRequest.
            request.ContentLength = byteArray.Length;
            request.CookieContainer = new CookieContainer();
            // Get the request stream.
            Stream dataStream;

            WebResponse response;
            try
            {
                dataStream = request.GetRequestStream();
                // Write the data to the request stream.
                dataStream.Write(byteArray, 0, byteArray.Length);
                // Close the Stream object.
                dataStream.Close();
                // Get the response.
                response = request.GetResponse();

            }
            catch (WebException e)
            {
                LogWriter.Write("WebConnector.SendRequestGetUser: " + json, LogWriter.LogLevel.Error, null);
                //var reader = new StreamReader(stream: e.Response.GetResponseStream());
                //LogWriter.Write("WebConnector.SendRequestGetUser: " + reader.ReadToEnd(), LogWriter.LogLevel.Error, this);
                return null;
            }
#if DEBUG
            // Display the status.
            Console.WriteLine(@"status:"+((HttpWebResponse)response).StatusDescription);
#endif
            // Get the stream containing content returned by the server.
            dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            if (dataStream != null)
            {
                var reader = new StreamReader(dataStream);
                // Read the content.
                string responseFromServer = reader.ReadToEnd();
                // Display the content.
                Console.WriteLine(@"!!!!!!!!-" + responseFromServer + @"/!!!!!!!");


                if ((responseFromServer == "") || (responseFromServer.Contains("kein User mit der BMS-ID"))) return null;

                var jObject = JObject.Parse(responseFromServer);
                user.ImagePath = (jObject["ImageUrl"] != null ) ? (string)jObject["ImageUrl"] : null;
                if (jObject["Hobbies"] != null) user.Hobbies = (string)jObject["Hobbies"];
                if (jObject["Timestamp"]!= null) user.Last_WebUpdate =  (int)   jObject["Timestamp"];
                if (jObject["UserInfo"] != null) user.UserInfo  =       (string)jObject["UserInfo"];
                // Clean up the streams.
                reader.Close();
            }
            if (dataStream != null) dataStream.Close();
            response.Close();
            return user;
        }

        private static void  SendRequest(string post, string mode)
        {
            var url = "";

            string postData = post + "&shaFromBMS=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
            switch(mode)
            {
                case"updateuser":
                    url = "http://www.schmidtwoch.com/sites/default/bms-actions/updateUser.php";
                    break;
                case "updatebms":
                    url = "http://www.schmidtwoch.com/sites/default/bms-actions/updateBMS.php";
                    break;
                case "updatebmsstatus":
                    url = "http://www.schmidtwoch.com/sites/default/bms-actions/updateBmsStatus.php";
                    break;
            }
#if DEBUG
            Console.WriteLine(@"SendRequest " + mode + "@" + postData);
            Console.WriteLine(@"an Url: "+url );
#endif
            // Create a request using a URL that can receive a post. 
            var request = (HttpWebRequest)WebRequest.Create(url);
            // Set the Method property of the request to POST.
            request.Method = "POST";
            // Create POST data and convert it to a byte array.
            //string postData = "testname=TEST";
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            // Set the ContentType property of the WebRequest.
            request.ContentType = "application/x-www-form-urlencoded";
            // Set the ContentLength property of the WebRequest.
            request.ContentLength = byteArray.Length;
            request.CookieContainer = new CookieContainer();
            // Get the request stream.
            Stream dataStream = null;
            try
            {
                dataStream = request.GetRequestStream();
                // Write the data to the request stream.
                dataStream.Write(byteArray, 0, byteArray.Length);
                // Close the Stream object.
                dataStream.Close();
            }
            catch (WebException e)
            {
                if (e.Response != null)
                {
                    LogWriter.Write("WebConnector.SendRequest: " + url + "\n" + postData, LogWriter.LogLevel.Error, null);
                    //var reader = new StreamReader(e.Response.GetResponseStream());
                    //LogWriter.Write("WebConnector.sendRequestGetUser: " + reader.ReadToEnd(), LogWriter.LogLevel.Error, null);
                }
            }
            
            // Get the response.
            HttpWebResponse response = null;
            var cc = new CookieContainer();
            request.CookieContainer = cc;
            

            try
            {
                request.GetRequestStream();
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                if (e.Response != null)
                {
                    LogWriter.Write("WebConnector.SendRequest: " + url + "\n" + postData, LogWriter.LogLevel.Error, null);
                    //var reader = new StreamReader(e.Response.GetResponseStream());
                    //LogWriter.Write("WebConnector.sendRequestGetUser: " + reader.ReadToEnd(), LogWriter.LogLevel.Error, null);
                    return;
                }
            }
            
#if DEBUG
            // Display the status.
            //Console.WriteLine(mode +@"/Response: " +((HttpWebResponse)response).StatusDescription);
#endif
            // Get the stream containing content returned by the server.
            if (response != null) dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            if (dataStream != null)
            {
                var reader = new StreamReader(dataStream);
                // Read the content.
                string responseFromServer = reader.ReadToEnd();
                // Display the content.
                Console.WriteLine(mode +"/"+responseFromServer);
                Console.WriteLine(mode + @"/RequestEnd");
                // Clean up the streams.
                reader.Close();
            }
            if (dataStream != null) dataStream.Close();
            if (response != null) response.Close();
        }

        public void SendTransaction(User currentUser)
        {
            var post = "WebUser=" 
                          + ConvertToJson(currentUser)
                          + "&modus=update";

            SendRequest(post, "updateuser");
        }

        public void UpdateWebProfiles(List<User> userList)
        {
            var post = "WebUser=";
            var webUserList = userList.Select(ConvertToWebUser).ToList();

            post += ConvertToJson(webUserList);
            SendRequest(post, "updateuser");
        }

        public User GetUserInfo(User user)
        {
            
            return SendRequestGetUser(user);
        }

        public void UpdateBmsRanking(int barrelCount, Ranking ranking)
        {
            var bmsData = new BmsData[1];
            bmsData[0] = new BmsData
                {
                    FieldAnzahlDerBiereAktuelles = barrelCount,
                    FieldAnzahlBiereInsgesamt = Ranking.GetTotalBeerCount(),
                    FieldBierDiesenMonatGezapft = Ranking.GetMonthBeerCount(),
                    FieldBierHeuteAbendGezapft = Ranking.GetDayBeerCount()
                };

            string json = JsonConvert.SerializeObject(bmsData);
            SendRequest("bmsData=" + json, "updatebms");
        }

        public void UpdateBmsStatus(int status)
        {
            string post = "bmsData=" + "[{\"FieldBmsStatus\":" + status + "}]";
            try
            {
                SendRequest(post, "updatebmsstatus");
            }
            catch (WebException e)
            {
                if (e.Response != null)
                {
                    LogWriter.Write("WebConnector.SendRequest: " + post, LogWriter.LogLevel.Error, null);
                    //var reader = new StreamReader(e.Response.GetResponseStream());
                    //LogWriter.Write("WebConnector.UpdateBmsStatus: " + reader.ReadToEnd(), LogWriter.LogLevel.Error, this);
                }
            }
            
        }

        internal void UpdateWebProfile(User user)
        {
            //var post = "WebUser=";
            //var webUserList = userList.Select(ConvertToWebUser).ToList();

            //post += ConvertToJson(webUserList);
            //SendRequest(post, "updateuser");
        }

        #region Conversions

        public WebUser ConvertToWebUser(User u)
        {
            return new WebUser
                {
                    Id = u.ID,
                    BeerDay = Convert.ToInt32(u.Beer_day),
                    BeerMonth = Convert.ToInt32(u.Beer_month),
                    BeerTotal = Convert.ToInt32(u.Beer_total),
                    AccountBeerbill = Convert.ToDecimal(u.Account_beerbill),
                    DurationTotal = Convert.ToDecimal(u.Duration_total),
                    Title = u.Title
                };
        }
        
        private string ConvertToJson(User user)
        {
            var oSerializer = new JavaScriptSerializer();
            var webUser = ConvertToWebUser(user);

            var list = new List<WebUser>
                {
                    webUser
                };
            return oSerializer.Serialize(list);
        }

        private string ConvertToJson(List<WebUser> list )
        {
            var oSerializer = new JavaScriptSerializer();
            
            return oSerializer.Serialize(list);
        }

        public static DateTime ConvertFromUnixTimestamp(double timestamp)
        {

            var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);

            return origin.AddSeconds(timestamp);

        }

        public long ToUnixTimespan(DateTime dateTime)
        {
            var tspan = dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1, 0, 0, 0));

            return (long)Math.Truncate(tspan.TotalSeconds);
        }
        #endregion  
    }

    class WebUser
    {
        public int Id { get; set; }
        public int BeerTotal { get; set; }
        public int BeerMonth { get; set; }
        public int BeerDay { get; set; }
        public decimal DurationTotal{ get; set; }
        public decimal AccountBeerbill { get; set; }
        public string Title { get; set; }
    }

    class WebUserGetInfo
    {
        public int Id { get; set; }
        public long Timestamp { get; set; }
      
    }

    class BmsData
    {
        public int FieldAnzahlDerBiereAktuelles { get; set; }
        public int FieldAnzahlBiereInsgesamt { get; set; }
        public int FieldBierHeuteAbendGezapft { get; set; }
        public int FieldBierDiesenMonatGezapft { get; set; }
    }
    
}

//string post = "bmsData=" +
//                          "[{" +
//                          "\"field_anzahl_der_biere_aktuelles\":" + currentUser.ID +
//                          ",\"field_anzahl_biere_insgesamt\":" + currentUser.Beer_total +
//                          ",\"field_bier_heute_abend_gezapft\":" + currentUser.Beer_month +
//                          ",\"field_bier_diesen_monat_gezapft\":" + currentUser.Beer_day +
//                          "}]";
